﻿Type.registerNamespace("MoniMisi2");

MoniMisi2.ProveedorDatosServidor = function(element) {
    MoniMisi2.ProveedorDatosServidor.initializeBase(this, [element]);
    this.Indices = null;
    this.IndiceActual = null;
    this.PaginaActual = null;
    this.RegistroActual = null;
    this.Ordenes = null;
    this.Defectos = null;
    this.WebMethod = null;
    this.DelConsultaOK = Function.createDelegate(this, this.ConsultaOK);
    this.DelConsultaError = Function.createDelegate(this, this.ConsultaError);
    this.Argumentos = null;
    this.Asincronico = null;
    this.FinDeArchivo = false
    this.PrincipioDeArchivo = false
    this.Filtro = null;
    this.Expand = null;
    this.ExpandUpdate = null;
    this.Select = null;
    this.Top = null;
    this.FiltroCliente = function(pRegistro) { return true; }
    this.Registro = null;
    this.Puntero = { Indice: 0, Pagina: 0, Registro: 0 };
    this.Esperando = false;
    this.Estructura = null;
    this.REST = false;
    this.OData = false;
    this.ODVersion = 3;
    this.LlamarMetodo = null;
    this.LlamarParametros = null;
    this.UltimaOperacion = null;
    this.Modelo;
    this.OrdenDefecto = null;
    this.DatoRaiz = null;
    this.InlineCount = false;
    this.Count = 0;
};

MoniMisi2.ProveedorDatosServidor.prototype = {
    initialize: function() {
        MoniMisi2.ProveedorDatosServidor.callBaseMethod(this, 'initialize');
        this.Contrato = function(pMetodo, pDesde, pHasta, pClave, pOrden, pOperacion, pFiltro) {
            this.Metodo = pMetodo;
            this.Orden = pOrden;
            this.Desde = pDesde;
            this.Hasta = pHasta;
            this.Clave = pClave;
            this.Operacion = pOperacion;
            this.Filtro = pFiltro;
        }
        this.Pagina = function(pClave, pDesde, pHasta) {
            this.Clave = pClave;
            this.Desde = pDesde;
            this.Hasta = pHasta
        }
        this.Metodo = function(pAccion, pNombre, pParametros) {
            this.Accion = pAccion;
            this.Nombre = pNombre;
            this.Parametros = pParametros;
        }
        this.Operacion = function(pNombre, pValor) {
            this.Nombre = pNombre;
            this.Valor = pValor;
        }

        if (this.OrdenDefecto == null) {
            this.IndiceActual = 0
        } else {
            this.IndiceActual = this.IndiceOrden(this.OrdenDefecto)
        };
        if (!this.Independiente) {
            if (document._MoniMisi2Datos == undefined) {
                document._MoniMisi2Datos = {}
            };
            if (document._MoniMisi2Datos[this.WebMethod] == undefined) {
                document._MoniMisi2Datos[this.WebMethod] = []
            };
            this.Indices = document._MoniMisi2Datos[this.WebMethod]
        } else {
            this.Indices = [];
        }
    },

    dispose: function() {
        MoniMisi2.ProveedorDatosServidor.callBaseMethod(this, 'dispose');
    },

    ValidarParametros: function(Argumentos, Esperados) {
        var Devuelto = null;
        if (Argumentos) {
            var Propiedad = ""
            for (var n = 0; n < Esperados.length; n = n + 1) {

                if (Argumentos[Esperados[n].Nombre] == null) {
                    Argumentos[Esperados[n].Nombre] = Esperados[n].Defecto
                }
                if (Argumentos[Esperados[n].Nombre] == undefined) {
                    throw new Error("No se asignó el parámetro " + Esperados[n].Nombre)
                }
                if (Esperados[n].Tipo != "object" && typeof (Argumentos[Esperados[n].Nombre]) != Esperados[n].Tipo) {
                    throw new Error("El parámetro " + Esperados[n].Nombre + " debe ser del tipo " + Esperados[n].Tipo)
                }

            }
            Devuelto = Argumentos;
        } else {
            var Armado = ""
            for (var n = 0; n < Esperados.length; n = n + 1) {
                Armado += "," + Esperados[n].Nombre + ":''";
            }
            Armado = "{" + Armado.substring(1) + "}";
            eval("Devuelto = " + Armado);
            for (var n = 0; n < Esperados.length; n = n + 1) {
                Devuelto[Esperados[n].Nombre] = Esperados[n].Defecto;
            }

        }
        return Devuelto;
    },

    Avanzar: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Salto", Tipo: "number", Defecto: 1}])
        if (this.RegistroActual != null) {
            var Resto = this.RegistroActual + Parametros.Salto - this.Indices[this.IndiceActual][this.PaginaActual].P.length;
            if (Resto >= 0) {
                if (this.PaginaActual + 1 > this.Indices[this.IndiceActual].length - 1) {
                    this.InvocarFin()
                } else {
                    Parametros.Salto = Resto;
                    this.PaginaActual = this.PaginaActual + 1;
                    if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") {
                        var Entre = this.EntrePaginas(this.PaginaActual)
                        var Metodo = new this.Metodo("P", "Avanzar", pParametros);
                        var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                        this.ConsultaServidor(Contrato);
                    } else {
                        this.RegistroActual = 0
                        this.Avanzar(Parametros);
                    }
                }
            } else {
                this.RegistroActual = this.RegistroActual + Parametros.Salto;
                if (this.FiltroCliente(this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual])) {
                    this.InvocarEncontrado()
                } else {
                    this.Avanzar({ Salto: 1 });
                }
            }
        }
    },

    Retroceder: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Salto", Tipo: "number", Defecto: 1}]);
        if (this.RegistroActual != null) {
            var Resto = Parametros.Salto - this.RegistroActual - 1;
            if (Resto >= 0) {
                if (this.PaginaActual - 1 < 0) {
                    this.InvocarPrincipio()
                } else {
                    Parametros.Salto = Resto;
                    this.PaginaActual = this.PaginaActual - 1;
                    if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") {
                        var Entre = this.EntrePaginas(this.PaginaActual)
                        var Metodo = new this.Metodo("P", "Retroceder", Parametros);
                        var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                        this.ConsultaServidor(Contrato);
                    } else {
                        this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1;
                        this.Retroceder(Parametros);
                    }
                }
            } else {
                this.RegistroActual = this.RegistroActual - Parametros.Salto;
                if (this.RegistroActual >= 0) {
                    if (this.FiltroCliente(this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual])) {
                        this.InvocarEncontrado()
                    } else {
                        this.Retroceder(Parametros);
                    }
                } else {
                    this.InvocarPrincipio()
                }
            }
        }
    },

    Arribar: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Orden", Tipo: "number", Defecto: this.IndiceActual }, { Nombre: "Pagina", Tipo: "number", Defecto: 0}]);
        this.IndiceActual = Parametros.Orden
        this.PaginaActual = Parametros.Pagina;
        if (this.Indices[this.IndiceActual] == undefined) { // Voy a buscar el indice que falta
            var Metodo = new this.Metodo("IP", "Arribar", Parametros);
            var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Leer", this.PaginaActual), null);
            this.ConsultaServidor(Contrato);
        } else {
            if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") { // Voy a Buscar pagina
                var Entre = this.EntrePaginas(this.PaginaActual)
                var Metodo = new this.Metodo("P", "Arribar", Parametros);
                var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                this.ConsultaServidor(Contrato);
            } else {
                this.RegistroActual = 0
                if (this.FiltroCliente(this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual])) {
                    this.InvocarEncontrado()
                } else {
                    this.Avanzar({ Salto: 1 });
                }
            }
        }
    },

    Fondear: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Orden", Tipo: "number", Defecto: this.IndiceActual }, { Nombre: "Pagina", Tipo: "number", Defecto: -1}]);
        this.IndiceActual = Parametros.Orden
        this.PaginaActual = Parametros.Pagina;
        if (this.Indices[this.IndiceActual] == undefined) { // Voy a buscar el indice que falta
            var Metodo = new this.Metodo("IPF", "Fondear", pParametros);
            var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Leer", this.PaginaActual), null);
            this.ConsultaServidor(Contrato);
        } else {
            this.PaginaActual = Parametros.Pagina != -1 ? Parametros.Pagina : this.Indices[this.IndiceActual].length - 1;
            if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") { // Voy a Buscar pagina
                var Entre = this.EntrePaginas(this.PaginaActual)
                var Metodo = new this.Metodo("P", "Fondear", Parametros);
                var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                this.ConsultaServidor(Contrato);
            } else {
                this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1;
                this.InvocarEncontrado()
            }
        }
    },

    Buscar: function(pParametros) {
        if (this.Ordenes.length > 0) {
            var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Orden", Tipo: "number", Defecto: this.IndiceActual }, { Nombre: "Valor", Tipo: "object", Defecto: ""}]);
            this.IndiceActual = Parametros.Orden;
            if (this.Indices[this.IndiceActual] == undefined) { // Voy a buscar el indice que falta
                var Metodo = new this.Metodo("IP", "Buscar", Parametros);
                var Contrato = new this.Contrato(Metodo, null, null, Parametros.Valor, null, null, null);
                this.ConsultaServidor(Contrato);
            } else {
                this.PaginaActual = this.EncontrarValor(Parametros.Valor, "I", "C");
                var Entre = this.EntrePaginas(this.PaginaActual)
                if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") { // Voy a Buscar pagina
                    var Metodo = new this.Metodo("P", "Buscar", Parametros);
                    var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                    this.ConsultaServidor(Contrato);
                } else {
                    this.RegistroActual = this.EncontrarValor(Parametros.Valor, "P", this.Ordenes[this.IndiceActual].Columna);
                    if (this.RegistroActual > this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1) {
                        this.Fondear();
                    } else {
                        this.InvocarEncontrado()
                    }
                }
            }
        }
    },
    Actualizar: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "Registros", Tipo: "object", Defecto: "" }, { Nombre: "Volviendo", Tipo: "boolean", Defecto: false}])
        var Metodo = new this.Metodo("", "RetornoActualizar", Parametros);
        var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Actualizar", Parametros), null);
        this.ConsultaServidor(Contrato);
    },
    RetornoActualizar: function(pParametros) {
        this.InvocarActualizado();
    },
    Agregar: function(pParametros) {
        var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "RegistroActual", Tipo: "object", Defecto: "" }, { Nombre: "Volviendo", Tipo: "boolean", Defecto: false}])
        var Metodo = new this.Metodo("", "RetornoAgregar", Parametros);
        var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Agregar", Parametros), null);
        this.ConsultaServidor(Contrato);
    },
    RetornoAgregar: function(pParametros) {
        //Si no esta volviendo de Leer pagina donde esta el registro que se modifico
        if (!pParametros.Volviendo) {
            if (this.Indices[this.IndiceActual] == undefined) { // Voy a buscar el indice que falta
                pParametros.Volviendo = true;
                var Metodo = new this.Metodo("IP", "RetornoAgregar", pParametros);
                var Contrato = new this.Contrato(Metodo, null, null, pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], null, null, null);
                this.ConsultaServidor(Contrato);
            } else {
                // Me fijo en que pagina deberia estar el nuevo valor
                if (this.Ordenes.length != 0) {
                    this.PaginaActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "I", "C");
                    var Entre = this.EntrePaginas(this.PaginaActual)
                    // Si no existe la pagina la traigo del servidor
                    if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") {
                        pParametros.Volviendo = true;
                        var Metodo = new this.Metodo("P", "RetornoAgregar", pParametros);
                        var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                        this.ConsultaServidor(Contrato);
                    } else {
                        this.RegistroActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "P", this.Ordenes[this.IndiceActual].Columna);
                        this.Indices[this.IndiceActual][this.PaginaActual].P.splice(this.RegistroActual, 0, pParametros.RegistroActual);
                        this.LimpiarResto(this.IndiceActual);
                        this.InvocarAgregado();
                    }
                } else {
                    this.Indices[this.IndiceActual][this.PaginaActual].P.push(pParametros.RegistroActual);
                    this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1;
                    this.InvocarAgregado();
                }
            }
        } else {
            this.PaginaActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "I", "C"); ;
            this.RegistroActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "P", this.Ordenes[this.IndiceActual].Columna);
            this.LimpiarResto(this.IndiceActual);
            this.InvocarAgregado();
        };
    },




    Modificar: function(pParametros) {
        if (this.RegistroActual != null) {
            var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "RegistroAnterior", Tipo: "object", Defecto: this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual] }, { Nombre: "RegistroActual", Tipo: "object", Defecto: ""}]);
            var Metodo = new this.Metodo("", "RetornoModificar", Parametros);
            var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Modificar", Parametros), null);
            this.ConsultaServidor(Contrato)
        };
    },
    RetornoModificar: function(pParametros) {
        //Si no esta volviendo de Leer pagina donde esta el registro que se modifico
        if (pParametros.RegistroAnterior != null) {
            // Si no tiene Indices
            if (this.Ordenes[this.IndiceActual] != undefined) {
                //Si cambio la columna clave
                if (pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna] != this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual][this.Ordenes[this.IndiceActual].Columna]) {
                    //Limpio el registro
                    this.Indices[this.IndiceActual][this.PaginaActual].P.splice(this.RegistroActual, 1);
                    // Me fijo en que pagina deberia estar el nuevo valor
                    this.PaginaActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "I", "C");
                    var Entre = this.EntrePaginas(this.PaginaActual)
                    // Si no existe la pagina la traigo del servidor
                    if (this.Indices[this.IndiceActual][this.PaginaActual].P == "") {
                        pParametros.RegistroAnterior = null;
                        var Metodo = new this.Metodo("P", "RetornoModificar", pParametros);
                        var Contrato = new this.Contrato(Metodo, Entre.Desde, Entre.Hasta, null, null, null, null);
                        this.ConsultaServidor(Contrato);
                    } else {
                        this.RegistroActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "P", this.Ordenes[this.IndiceActual].Columna);
                        this.Indices[this.IndiceActual][this.PaginaActual].P.splice(this.RegistroActual, 0, pParametros.RegistroActual);
                        this.LimpiarResto(this.IndiceActual);
                        this.InvocarModificado();
                    }
                } else {
                    this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual] = pParametros.RegistroActual;
                    this.LimpiarResto(this.IndiceActual);
                    this.InvocarModificado();
                }
            } else {
                this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual] = pParametros.RegistroActual;
                this.InvocarModificado();
            }
        } else {
            this.RegistroActual = this.EncontrarValor(pParametros.RegistroActual[this.Ordenes[this.IndiceActual].Columna], "P", this.Ordenes[this.IndiceActual].Columna);
            this.InvocarModificado();
        };

    },

    Eliminar: function(pParametros) {
        if (this.RegistroActual != null) {
            var Parametros = this.ValidarParametros(pParametros, [{ Nombre: "RegistroAnterior", Tipo: "object", Defecto: this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual]}]);
            var Metodo = new this.Metodo("", "RetornoEliminar", Parametros);
            var Contrato = new this.Contrato(Metodo, null, null, null, null, new this.Operacion("Eliminar", Parametros), null);
            this.ConsultaServidor(Contrato);
        }
    },

    RetornoEliminar: function(pParametros) {
        this.Indices[this.IndiceActual][this.PaginaActual].P.splice(this.RegistroActual, 1);
        this.LimpiarResto(this.IndiceActual);
        if (this.RegistroActual > this.Indices[this.IndiceActual][this.PaginaActual].P.length) {
            this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1;
            if (this.RegistroActual < 0) {
                this.InvocarPrincipio();
            }
        }
        this.InvocarEliminado();
    },

    Limpiar: function(pParametros) {
        pParametros = pParametros ? pParametros : { Orden: this.IndiceActual };
        this.IndiceActual = pParametros.Orden;
        if (pParametros.Orden) {
            this.Indices[this.IndiceActual] = null;
        } else {
            this.Indices = new Array();
        }
        this.RegistroActual = null;
    },

    LimpiarResto: function(pOrden) {
        for (var Ind = 0; Ind < this.Indices.length; Ind += 1) {
            if (Ind != pOrden) {
                this.Indices[Ind] = null;
            }
        }
    },
    InvocarEncontrado: function() {
        this.FinDeArchivo = false;
        this.PrincipioDeArchivo = false;
        this.InvocarEvento('Encontrado')
    },
    InvocarFin: function() {
        this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1; ;
        this.FinDeArchivo = true;
        this.InvocarEvento('Fin')
    },
    InvocarPrincipio: function() {
        this.RegistroActual = 0;
        this.PrincipioDeArchivo = true;
        this.InvocarEvento('Principio')
    },
    InvocarActualizado: function() { this.InvocarEvento('Actualizado') },
    InvocarAgregado: function() {
        this.FinDeArchivo = false;
        this.PrincipioDeArchivo = false;
        this.InvocarEvento('Agregado')
    },
    InvocarModificado: function() { this.InvocarEvento('Modificado') },
    InvocarEliminado: function() { this.InvocarEvento('Eliminado') },
    IrA: function(pPuntero) {
        if (this.Indices.length > 0) {
            this.IndiceActual = pPuntero.Indice;
            this.PaginaActual = pPuntero.Pagina
            this.RegistroActual = pPuntero.Registro;
            this.Registro = this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual];
            this.Puntero = pPuntero;
        }
    },
    InvocarEvento: function(pEvento) {
        this.Puntero = { Indice: this.IndiceActual, Pagina: this.PaginaActual, Registro: this.RegistroActual };
        this.Registro = this.Indices[this.IndiceActual][this.PaginaActual].P[this.RegistroActual];
        var h = this.get_events().getHandler(pEvento);
        if (h) { h(this, this.Registro) };
    },

    ConsultaServidor: function(pContrato) {
        pContrato.Filtro = this.Filtro;
        pContrato.Orden = this.IndiceActual;
        pContrato.Operacion = pContrato.Operacion ? pContrato.Operacion : new this.Operacion("Leer", "");
        this.LlamarMetodo = pContrato.Metodo.Nombre;
        this.LlamarParametros = pContrato.Metodo.Parametros;

        this.Esperando = true;
        if (!this.REST) {
            var Funciones = new MoniMisi2.Funciones()
            Funciones.InvocarWebMethod(this.WebMethod, { pContrato: pContrato }, this.DelConsultaOK, this.DelConsultaError, this.Asincronico);
        } else {
            var Funciones = new MoniMisi2.Funciones()
            var Oper = "GET";
            var Reg = pContrato.Operacion.Valor.RegistroActual
            var Uri = this.WebMethod
            switch (pContrato.Operacion.Nombre) {
                case "Agregar":
                    Oper = "POST";
                    break;
                case "Modificar":
                    Oper = "PUT";
                    if (this.OData) {
                        if (Uri.indexOf("?") == -1) {
                            Uri += "(" + pContrato.Operacion.Valor.RegistroAnterior.Id + ")";
                        } else {
                            Uri = Uri.substr(0, Uri.indexOf("?")) + "(" + pContrato.Operacion.Valor.RegistroAnterior.Id + ")" + Uri.substr(Uri.indexOf("?"));
                        };
                    }
                    break;
                case "Eliminar":
                    Oper = "DELETE";
                    Reg = pContrato.Operacion.Valor.RegistroAnterior
                    if (this.OData) {
                        if (Uri.indexOf("?") == -1) {
                            Uri += "(" + pContrato.Operacion.Valor.RegistroAnterior.Id + ")";
                        } else {
                            Uri = Uri.substr(0, Uri.indexOf("?")) + "(" + pContrato.Operacion.Valor.RegistroAnterior.Id + ")" + Uri.substr(Uri.indexOf("?"));
                        };
                    }
                    break;
                case "Leer":
                    var CadenaParam = "";
                    var Prefijo = (this.OData ? "&$" : "&");
                    if (this.Ordenes.length > 0) {
                        CadenaParam += Prefijo + "orderby=" + this.Ordenes[this.IndiceActual].Columna;
                    }
                    if (this.Filtro != null) {
                        CadenaParam += Prefijo + "filter=" + this.Filtro;
                    }
                    if (this.Expand != null) {
                        CadenaParam += Prefijo + "expand=" + this.Expand;
                    }
                    if (this.Select != null) {
                        CadenaParam += Prefijo + "select=" + this.Select;
                    }

                    if (this.Top != null) {
                        CadenaParam += Prefijo + "top=" + this.Top;
                    }
                    if (this.InlineCount) {
                        CadenaParam += Prefijo + "inlinecount=allpages";
                    }

                    if (CadenaParam != "") {
                        Uri += (Uri.indexOf("?") == -1 ? "?" + CadenaParam.substring(1) : "" + CadenaParam);
                    }
                    break;

            }
            this.UltimaOperacion = Oper
            var RegModel = {};
            if (Oper != "GET") {
                for (var x in this.Modelo) {
                    var nombres = null;
                    if (x.indexOf("__") != -1 && this.ExpandUpdate != undefined) {
                        nombres = x.split("__")
                        if (this.ExpandUpdate.indexOf(nombres[0] + ",") != -1) {
                            if (RegModel[nombres[0]] == undefined) {
                                RegModel[nombres[0]] = Reg[nombres[0]];
                            }

                            var ultimo = RegModel[nombres[0]];
                            var n = 1;
                            while (n < nombres.length - 1 && ultimo != undefined) {
                                ultimo = ultimo[nombres[n]]
                            }
                            this.ODataAdapter(x, ultimo);
                        }
                    } else {
                        RegModel[x] = Reg[x];
                        this.ODataAdapter(x, RegModel);
                    }
                }
            }
            Funciones.Transfer(Uri, Oper, RegModel, this.DelConsultaOK, this.DelConsultaError, this.Asincronico);

        }
    },

    ODataAdapter: function(pColumna, pValor) {
        if (pValor != undefined) {
            var Columnas = pColumna.split("__");
            var Columna = Columnas[Columnas.length - 1];
            if (pValor[Columna] != undefined) {
                if (this.ODVersion == 3) {
                    if ("Int64-Decimal-Double-SByte-Single".indexOf(this.Modelo[pColumna]) != -1 && typeof (pValor[Columna]) != "string") {
                        pValor[Columna] = pValor[Columna].toString()
                    }
                }
                if (this.ODVersion == 4) {
                    if ("Int32-Int64-Decimal-Double-SByte-Single".indexOf(this.Modelo[pColumna]) != -1) {
                        pValor[Columna] = new Number(pValor[Columna]);
                    }
                }
            }
        }
    },

    ConsultaOK: function(pDatos) {
        this.Esperando = false;
        if (!this.REST) {
            if (pDatos.Estructura != undefined) {
                this.Estructura = pDatos.Estructura;
            }
            if (pDatos.Indice != undefined) {
                this.Indices[pDatos.Orden] = pDatos.Indice;
                this.IndiceActual = pDatos.Orden
            }
            if (pDatos.Pagina != undefined) {
                this.Indices[this.IndiceActual][this.PaginaActual].P = pDatos.Pagina;
            }
            if (pDatos.Metodo.Nombre == "Avanzar") {
                this.RegistroActual = 0;
            }
            if (pDatos.Metodo.Nombre == "Retroceder") {
                this.RegistroActual = this.Indices[this.IndiceActual][this.PaginaActual].P.length - 1;
            }
            if (pDatos.Metodo.Nombre != "") {
                var Llamado = Function.createCallback(eval("this." + pDatos.Metodo.Nombre), pDatos.Metodo.Parametros);
                Llamado.call(this)
            } else {
                this.InvocarFin();
            }
        } else {
            if (this.UltimaOperacion == "GET") {
                if (pDatos.value) {
                    this.Count = pDatos.value.length;
                } else {
                    this.Count = pDatos.length;
                };
                if (this.OData && this.InlineCount) {
                    this.Count = pDatos["odata.count"];
                }
                this.Indices[this.IndiceActual] = [{ C: "", P: ""}];

                if (this.OData) {
                    var props = this.DatoRaiz.split(".")
                    var c = 0
                    while (c < props.length) {
                        if (props[c] != null) {
                            pDatos = pDatos[props[c]]
                        }
                        c++
                    }

                }
                this.Indices[this.IndiceActual][this.PaginaActual].P = pDatos;

                var Funciones = new MoniMisi2.Funciones()
                this.Estructura = Funciones.Clonar(this.Modelo);
                if (this.Indices[this.IndiceActual][this.PaginaActual].P.length == 0) {
                    this.InvocarFin();
                } else {
                    var Llamado = Function.createCallback(eval("this." + this.LlamarMetodo), this.LlamarParametros);
                    Llamado.call(this)
                }
            } else {
                if (pDatos != "") {
                    this.LlamarParametros.RegistroActual = pDatos;
                }
                var Llamado = Function.createCallback(eval("this." + this.LlamarMetodo), this.LlamarParametros);
                Llamado.call(this)
            }

        }
        ;
    },

    ConsultaError: function(pError) {
        var args = pError.Message
        if (pError["odata.error"] != undefined) {
            if (pError["odata.error"]["custom.errors"] != undefined) {
                { args = pError["odata.error"]["custom.errors"] }
            } else {
                args = [{ "Codigo": "", "Mensaje": pError["odata.error"].innererror.message}]
            }
        }
        this.Esperando = false;
        var h = this.get_events().getHandler("Errado");
        if (h) {
            h(this, args)
        } else {
            alert("Error en Servidor: " + args);
        };

    },

    EncontrarValor: function(pValor, pIP, pColumna) {
        var Lista = (pIP == "I" ? this.Indices[this.IndiceActual] : this.Indices[this.IndiceActual][this.PaginaActual].P);
        var Mitad = 1;
        var MenorValor = 0;
        var MayorValor = Lista.length - 1;
        var ValorEncontrado = "";
        while (Mitad > 0) {
            Mitad = Math.round((MayorValor - MenorValor) / 2);
            ValorEncontrado = Lista[MenorValor + Mitad][pColumna];
            if (ValorEncontrado == undefined) { ValorEncontrado = "" };
            if (typeof (ValorEncontrado) == "string" && typeof (pValor) == "string") { pValor = pValor.toUpperCase(); ValorEncontrado = ValorEncontrado.toUpperCase() }
            if (pValor > ValorEncontrado) {
                MenorValor = MenorValor + Mitad;
            } else {
                MayorValor = MayorValor - Mitad;
            }
        }
        if (pIP == "P") { if (pValor > ValorEncontrado) { MenorValor += 1 } }

        return MenorValor
    },

    EntrePaginas: function(pSubIndice) {
        var Desde = ""
        var Hasta = ""
        if (pSubIndice == 0) {
            Desde = null;
        } else {
            Desde = this.Indices[this.IndiceActual][pSubIndice].C;
        }
        if (pSubIndice == this.Indices[this.IndiceActual].length - 1) {
            Hasta = null;
        } else {
            Hasta = this.Indices[this.IndiceActual][pSubIndice + 1].C;
        };
        return { Desde: Desde, Hasta: Hasta }
    },

    IndiceOrden: function(pNombreOrden) {
        var n = null;
        for (n = 0; n < this.Ordenes.length; n += 1) {
            if (this.Ordenes[n].Columna == pNombreOrden) {
                break;
            }
        }
        return n
    },

    Clonar: function() {
        var Reto = {};
        for (var Prop in this.Registro) {
            Reto[Prop] = this.Registro[Prop]
        };
        return Reto;
    },
    RegistroBlanco: function(pConDefecto) {
        var Reto = {}
        for (var n in this.Estructura) {
            var Defecto = null;
            if (pConDefecto) {
                for (var d = 0; d < this.Defectos.length; d += 1) {
                    if (this.Defectos[d].Columna == n) {
                        Defecto = this.Defectos[d].Valor;
                    }
                }
            }
            switch (this.Estructura[n]) {
                case "Boolean":
                    Reto[n] = (Defecto ? Defecto : false);
                    break;
                case "DateTime":
                    Reto[n] = (Defecto ? Defecto : new Date(0, 0, 0, 0, 0, 0));
                    break;
                case "String":
                    Reto[n] = (Defecto ? Defecto : "");
                    break;
                default:
                    Reto[n] = (Defecto ? Defecto : 0);
                    break;
            }

        }
        return Reto
    },

    get_WebMethod: function() {
        return this.WebMethod;

    },
    set_WebMethod: function(value) {
        if (this.WebMethod !== value) {
            this.WebMethod = value;
            this.raisePropertyChanged('WebMethod');
        }
    },
    get_Ordenes: function() {
        return this.Ordenes;

    },
    set_Ordenes: function(value) {
        if (this.Ordenes !== value) {
            this.Ordenes = value;
            this.raisePropertyChanged('Ordenes');
        }
    },
    get_Defectos: function() {
        return this.Defectos;

    },
    set_Defectos: function(value) {
        if (this.Defectos !== value) {
            this.Defectos = value;
            this.raisePropertyChanged('Defectos');
        }
    },

    get_Modelo: function() {
        return this.Modelo;

    },
    set_Modelo: function(value) {
        if (this.Modelo !== value) {
            this.Modelo = value;
            this.raisePropertyChanged('Modelo');
        }
    },
    get_Asincronico: function() {
        return this.Asincronico;

    },
    set_Asincronico: function(value) {
        if (this.Asincronico !== value) {
            this.Asincronico = value;
            this.raisePropertyChanged('Asincronico');
        }
    },
    get_REST: function() {
        return this.REST;

    },
    set_REST: function(value) {
        if (this.REST !== value) {
            this.REST = value;
            this.raisePropertyChanged('REST');
        }
    },
    get_OData: function() {
        return this.OData;

    },
    set_OData: function(value) {
        if (this.OData !== value) {
            this.OData = value;
            this.raisePropertyChanged('OData');
        }
    },

    get_ODVersion: function() {
        return this.ODVersion;

    },
    set_ODVersion: function(value) {
        if (this.ODVersion !== value) {
            this.ODVersion = value;
            this.raisePropertyChanged('ODVersion');
        }
    },



    get_Filtro: function() {
        return this.Filtro;

    },
    set_Filtro: function(value) {
        if (this.Filtro !== value) {
            this.Filtro = value;
            this.raisePropertyChanged('Filtro');
        }
    },

    get_Expand: function() {
        return this.Expand;

    },
    set_Expand: function(value) {
        if (this.Expand !== value) {
            this.Expand = value;
            this.raisePropertyChanged('Expand');
        }
    },

    get_ExpandUpdate: function() {
        return this.ExpandUpdate;

    },
    set_ExpandUpdate: function(value) {
        if (this.ExpandUpdate !== value) {
            this.ExpandUpdate = value + ",";
            this.raisePropertyChanged('ExpandUpdate');
        }
    },

    get_Top: function() {
        return this.Top;

    },
    set_Top: function(value) {
        if (this.Top !== value) {
            this.Top = value;
            this.raisePropertyChanged('Top');
        }
    },

    get_Select: function() {
        return this.Select;

    },
    set_Select: function(value) {
        if (this.Select !== value) {
            this.Select = value;
            this.raisePropertyChanged('Select');
        }
    },


    get_OrdenDefecto: function() {
        return this.OrdenDefecto;

    },
    set_OrdenDefecto: function(value) {
        if (this.OrdenDefecto !== value) {
            this.OrdenDefecto = value;
            this.raisePropertyChanged('OrdenDefecto');
        }
    },

    get_Independiente: function() {
        return this.Independiente;

    },
    set_Independiente: function(value) {
        if (this.Independiente !== value) {
            this.Independiente = value;
            this.raisePropertyChanged('Independiente');
        }
    },

    get_DatoRaiz: function() {
        return this.DatoRaiz;

    },
    set_DatoRaiz: function(value) {
        if (this.DatoRaiz !== value) {
            this.DatoRaiz = value;
            this.raisePropertyChanged('DatoRaiz');
        }
    },
    get_InlineCount: function() {
        return this.InlineCount;

    },
    set_InlineCount: function(value) {
        if (this.InlineCount !== value) {
            this.InlineCount = value;
            this.raisePropertyChanged('InlineCount');
        }
    },
    add_Encontrado: function(handler) {
        this.get_events().addHandler('Encontrado', handler);
    },
    remove_Encontrado: function(handler) {
        this.get_events().removeHandler('Encontrado', handler);
    },

    add_Errado: function(handler) {
        this.get_events().addHandler('Errado', handler);
    },
    remove_Errado: function(handler) {
        this.get_events().removeHandler('Errado', handler);
    },

    add_Actualizado: function(handler) {
        this.get_events().addHandler('Actualizado', handler);
    },
    remove_Actualizado: function(handler) {
        this.get_events().removeHandler('Actualizado', handler);
    },

    add_Agregado: function(handler) {
        this.get_events().addHandler('Agregado', handler);
    },
    remove_Agregado: function(handler) {
        this.get_events().removeHandler('Agregado', handler);
    },

    add_Modificado: function(handler) {
        this.get_events().addHandler('Modificado', handler);
    },
    remove_Modificado: function(handler) {
        this.get_events().removeHandler('Modificado', handler);
    },

    add_Eliminado: function(handler) {
        this.get_events().addHandler('Eliminado', handler);
    },
    remove_Eliminado: function(handler) {
        this.get_events().removeHandler('Eliminado', handler);
    },
    add_Fin: function(handler) {
        this.get_events().addHandler('Fin', handler);
    },
    remove_Fin: function(handler) {
        this.get_events().removeHandler('Fin', handler);
    },
    add_Principio: function(handler) {
        this.get_events().addHandler('Principio', handler);
    },
    remove_Principio: function(handler) {
        this.get_events().removeHandler('Principio', handler);
    }

};


MoniMisi2.ProveedorDatosServidor.registerClass('MoniMisi2.ProveedorDatosServidor', Sys.UI.Control);

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();